package com.dream21th.rule.engine.biz;

import com.dream21th.common.enums.RtnEnum;
import com.dream21th.common.exception.WebException;
import com.dream21th.rule.engine.entity.DroolsBaseInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.drools.core.io.impl.UrlResource;
import org.kie.api.KieServices;
import org.kie.api.builder.KieModule;
import org.kie.api.builder.KieRepository;
import org.kie.api.runtime.KieContainer;
import org.springframework.stereotype.Component;
import java.io.InputStream;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

/*
 * @Author dream21th
 **/
@Slf4j
@Component
public class DroolBiz {

    public final static ConcurrentHashMap<String,KieContainer> CONTAINER_MAP=new ConcurrentHashMap<>();

    public KieContainer kieContainer(DroolsBaseInfo droolsBaseInfo){
        KieContainer container = CONTAINER_MAP.get(droolsBaseInfo.getDroolsNum());
        if(Objects.nonNull(container)){
            return container;
        }
        String allUrl=droolsBaseInfo.getUrl()+droolsBaseInfo.getPackageName().replaceAll(".","/")+"/"
                +droolsBaseInfo.getVersion()+"/"+droolsBaseInfo.getJarName();
        log.info("规则全路径：{}",allUrl);
        try{
            KieServices kieServices = KieServices.Factory.get();
            //通过Resource资源对象加载jar包
            UrlResource resource = (UrlResource) kieServices.getResources().newUrlResource(allUrl);
            //通过Workbench提供的服务来访问maven仓库中的jar包资源，需要先进行Workbench的认证
            resource.setUsername(droolsBaseInfo.getUserName());
            resource.setPassword(droolsBaseInfo.getPassword());
            resource.setBasicAuthentication(droolsBaseInfo.getBasicAuthentication());
            //将资源转换为输入流，通过此输入流可以读取jar包数据
            InputStream inputStream = resource.getInputStream();
            //创建仓库对象，仓库对象中保存Drools的规则信息
            KieRepository repository = kieServices.getRepository();
            //通过输入流读取maven仓库中的jar包数据，包装成KieModule模块添加到仓库中
            KieModule kieModule = repository.addKieModule(kieServices.getResources().newInputStreamResource(inputStream));
            //基于KieModule模块创建容器对象，从容器中可以获取session会话
            KieContainer kieContainer = kieServices.newKieContainer(kieModule.getReleaseId());
            CONTAINER_MAP.put(droolsBaseInfo.getDroolsNum(),kieContainer);
            return kieContainer;
        }catch (Exception exception){
            log.error("获取容器异常：{}",exception);
            throw new WebException(RtnEnum.ERRROR);
        }
    }

    public void refreshContainer(String droolsNum){
        if(StringUtils.isEmpty(droolsNum)){
            CONTAINER_MAP.clear();
        }else {
            CONTAINER_MAP.remove(droolsNum);
        }
    }
}
